package com.dhms.vostok1.model

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.dhms.vostok1.data.fault.FaultTypeItemData
import com.dhms.vostok1.repository.CheckInstrumentRepository
import com.dhms.vostok1.repository.CheckInstrumentRepository.Companion.DEFAULT_SPEED_SHEET
import com.dhms.vostok1.repository.FaultRepository
import com.dhms.vostok1.repository.FaultRepository.Companion.DEFAULT_FAULT_LEVEL_LIST
import com.dhms.vostok1.service.net.NetworkApi
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch

class StartingViewModel(
    private val faultRepository: FaultRepository,
    private val checkInstrumentRepository: CheckInstrumentRepository
) : SettingViewModel() {

    private var _isSavedUserInfoGotten = MutableLiveData<Boolean?>(null)
    val isSavedUserInfoGotten get() = _isSavedUserInfoGotten

    private lateinit var userSharedPref: MMKV

    val faultLevelList = MutableStateFlow(DEFAULT_FAULT_LEVEL_LIST)
    val faultTypes = MutableStateFlow<List<FaultTypeItemData>?>(listOf())
    val checkInstrumentSpeedData = MutableStateFlow(DEFAULT_SPEED_SHEET)

    private val dataPrepareFunctions =
        listOf(::getFaultLevelList, ::getFaultFaultTypes, ::getCheckInstrumentRPMSheets)
    private val dataPrepareResults = dataPrepareFunctions.map {
        return@map false
    }.toMutableList()

    fun setUserSharedPreferences(sharedPref: MMKV) {
        userSharedPref = sharedPref
    }

    fun getSavedUserInfo() {
        val userPhone = userSharedPref.getString("user_phone", null)
        val password = userSharedPref.getString("password", null)
        val token = userSharedPref.getString("token", null)
        val organizationId = userSharedPref.getLong("organization_id", 0)
        val userId = userSharedPref.getLong("userId", 0)
        if (!userPhone.isNullOrEmpty() && !password.isNullOrEmpty() && !token.isNullOrEmpty()) {
            NetworkApi.token = token
            NetworkApi.organizationId = organizationId
            NetworkApi.userId = userId
            Log.d(TAG, "Got user info from sharedpref.")
            _isSavedUserInfoGotten.value = true
        } else {
            Log.e(
                TAG,
                "Failed to get user info from sharedpref or the info is null."
            )
            _isSavedUserInfoGotten.value = false
        }
    }

    fun prepareData() {
        dataPrepareFunctions.forEachIndexed { index, func ->
            viewModelScope.launch {
                func()
                dataPrepareResults[index] = true
            }
        }
    }

    fun isDataPreparedDone(): Boolean {
        if (dataPrepareResults.any { !it }) {
            return false
        }

        return true
    }

    private suspend fun getFaultLevelList() {
        faultLevelList.value = faultRepository.updateFaultLevel()
    }

    private suspend fun getFaultFaultTypes() {
        NetworkApi.organizationId?.let {
            faultTypes.value = faultRepository.updateFaultTypes(it)
        }
    }

    private suspend fun getCheckInstrumentRPMSheets() {
        checkInstrumentSpeedData.value = checkInstrumentRepository.updateCheckInstrumentSpeedSheet()
    }

    companion object {
        private const val TAG = "StartingViewModel"
    }
}

class StartingViewModelFactory(
    private val faultRepository: FaultRepository,
    private val checkInstrumentRepository: CheckInstrumentRepository
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(StartingViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return StartingViewModel(faultRepository, checkInstrumentRepository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
